﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Client.Panels
{
    public abstract class GGYLPanel<TModel> : BasePanel
    {
        protected override string[] parentsName => new string[] { "BasePanel" };
        protected DataCenter.Models.StockInfo[] stockInfos;
        protected Dictionary<string, object> ggylInfo;
        string fls;

        protected Dictionary<string, MyConst.Span> flMap = new Dictionary<string, MyConst.Span>();

        public GGYLPanel(string fls, string clientText):base(clientText)
        {
            this.fls = fls;
            FillFields<TModel>(panelName);
        }

        public override void PageDown()
        {
            if (y == items.Count - 1)
                return;
            for (int i = y+1; i < items.Count; i++)
            {
                if (items[i].Count == 1)
                {
                    y = i;
                    SpeakCell();
                    break;
                }
            }
        }
        public override void PageUp()
        {
            if (y == 0)
                return;
            for(int i = y - 1; i >= 0; i--)
            {
                if (items[i].Count == 1)
                {
                    y = i;
                    SpeakCell();
                    return;
                }
            }
        }

        async Task<int> UpdateData()
        {
            try
            {
                ggylInfo = await DataCenter.DataCenter.GGYL(fls);
                List<string> tmp = new List<string>();
                int endP = 0;
                foreach(string i in ggylInfo.Keys)
                {
                    var s = ggylInfo[i] as DataCenter.Models.Symbol[];
                    if (s != null)
                    {
                        var span = new MyConst.Span();
                        span.startPoint = endP;
                        endP += s.Length;
                        span.endPoint = endP - 1;
                        flMap[i] = span;
                        tmp.AddRange(GetSymbols(s));
                    }
                    else
                    {
                        Console.WriteLine(i);
                    }
                
                }
                Managers.Manager.cronM.UpdateGGSymbol(tmp.ToArray());
            }
            catch (DataCenter.MyException.APIReturnException e)
            {
                var l = e.Message.Split('~');
                if (l[0] == "1000")
                    Utility.ShowLoginAgain();
                throw;
            }
            return 0;
        }

        string[] GetSymbols(DataCenter.Models.Symbol[] symbolModels)
        {
            string[] res = new string[symbolModels.Length];
            for(int i = 0; i < symbolModels.Length; i++)
            {
                res[i] = symbolModels[i].symbol;
            }

            return res;
        }

        protected void SuccessUpdate()
        {
            stockInfos = Managers.Manager.cronM.ggStocks;
            FillModelsWithGGInfo();
            UpdatePanel<TModel>();
            UpdateHotStockInfo();
        }

        protected void FillModelsWithGGInfo()
        {
            foreach (string k in ggylInfo.Keys)
            {
                var l = ggylInfo[k] as DataCenter.Models.NameAndTrade[];
                int point = flMap[k].startPoint;
                for (int i = 0; i < l.Length; i++)
                {
                    l[i].name = stockInfos[point + i].name;
                    l[i].trade = stockInfos[point + i].trade;
                }
            }
        }

        protected void UpdatePanel<T>()
        {
            items = new List<MyPanel.Item>();
            foreach(string k in ggylInfo.Keys)
            {
                var titleIt = new MyPanel.Item();
                titleIt.AddCell(Managers.Manager.jargonM.GetJargon(k));
                items.Add(titleIt);

                var data = ggylInfo[k] as T[];
                foreach (T i in data)
                {
                    var it = new MyPanel.Item();
                    foreach (var j in fields)
                    {
                        it.AddCell(ToText(j.GetGetMethod().Invoke(i, null)));
                    }
                    items.Add(it);
                }
            }
        }

        protected override void UpdateHotStockInfo()
        {
            if(y>-1 && items[y].Count > 1)
            {
                int x = 0;
                for(int i = y; i >= 0; i--)
                {
                    if (items[i].Count == 1)
                        x++;
                }
                StockMenuFuncs.UpdateHotStockInfo(stockInfos[y - x]);
            }
            else
            {
                Managers.Manager.hotStockInfo = null;
            }
        }

        public override void OnAwake()
        {
            base.OnAwake();
            Managers.Manager.cronM.beginCron += UpdateData;
            Managers.Manager.cronM.updateSuccessfully += SuccessUpdate;
            Managers.Manager.cronM.StartCron(true);
        }
        public override void OnSleep()
        {
            base.OnSleep();
            Managers.Manager.cronM.beginCron -= UpdateData;
            Managers.Manager.cronM.updateSuccessfully -= SuccessUpdate;
            Managers.Manager.hotStockInfo = null;
        }
        protected override void ClearCron()
        {
            Managers.Manager.cronM.ClearGGSymbols();
        }
    }

    //=========================================

    class ZFBPanel : GGYLPanel<DataCenter.Models.ZDB>
    {
        public ZFBPanel() : base("zftop10,dftop10,zf5day,df5day", "涨幅榜") { }
    }

    public class HSBPanel : GGYLPanel<DataCenter.Models.HSTop>
    {
        public HSBPanel() : base("hstop10,hs5day", "换手率Top10") { }
    }

    class GGZLZJPanel : GGYLPanel<DataCenter.Models.ZLLR>
    {
        public GGZLZJPanel() : base("zllr,zllc", "主力流入/流出") { }
    }

    class DDPXPanel : GGYLPanel<DataCenter.Models.HSTop>
    {
        public DDPXPanel() : base("ddpx_buy,ddpx_sell", "大单频现") { }
    }
    class CJEBPanel : GGYLPanel<DataCenter.Models.CJETop>
    {
        public CJEBPanel() : base("cjetop10", "成交量Top10") { }
    }
}
